package timing.ukulele.seal.service.minio;

import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.PostPolicy;
import io.minio.errors.*;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

/**
 * PreSigned的相关操作封装
 */
@Service
public class PreSignedService {
    private final MinioClient client;

    public PreSignedService(MinioClient client) {
        this.client = client;
    }

    /**
     * 生成一个给HTTP GET请求用的presigned URL。浏览器/移动端的客户端可以用这个URL进行下载，
     * 即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间，默认值是7天
     *
     * @param bucketName 存储桶名称
     * @param objectName 存储桶里的对象名称
     * @param expires    失效时间（以秒为单位），默认是7天，不得大于七天。
     * @return 连接地址
     * @throws IOException               连接异常
     * @throws InvalidKeyException       不合法的access key或者secret key
     * @throws NoSuchAlgorithmException  找不到相应的签名算法
     * @throws InsufficientDataException 在读到相应length之前就得到一个EOFException
     * @throws InternalException         内部错误
     * @throws ErrorResponseException    执行失败异常
     * @throws InvalidResponseException
     * @throws ServerException
     * @throws XmlParserException
     */
    public String preSignedGetObject(String bucketName, String objectName, Integer expires) throws IOException, InvalidKeyException, InvalidResponseException,
            InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        String url;
        if (expires == null)
            url = client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).build());
        else
            url = client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).expiry(expires).build());
        return url;
    }


    /**
     * 允许给POST请求的presigned URL设置策略，比如接收对象上传的存储桶名称的策略，key名称前缀，过期策略
     *
     * @param policy 对象的post策略
     * @return
     * @throws IOException                连接异常
     * @throws InvalidKeyException        不合法的access key或者secret key
     * @throws NoSuchAlgorithmException   找不到相应的签名算法
     * @throws InsufficientDataException  在读到相应length之前就得到一个EOFException
     * @throws InternalException          内部错误
     * @throws ErrorResponseException     执行失败异常
     * @throws InvalidResponseException
     * @throws ServerException
     * @throws XmlParserException
     */
    public Map<String, String> preSignedPostPolicy(PostPolicy policy) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException,
            NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        Map<String, String> formData = client.getPresignedPostFormData(policy);
        return formData;
    }
}
